package org.skydiveapp2;

import java.util.Date;

import org.skydiveapp2.ui.InterfaceManager;
import org.skydiveapplibrary.data.Rig;
import org.skydiveapplibrary.data.RigComponent;
import org.skydiveapplibrary.data.RigReminder;
import org.skydiveapplibrary.data.TimeUnit;
import org.skydiveapplibrary.data.RigReminder.DueStatus;
import org.skydiveapplibrary.repository.RigRepository;
import org.skydiveapplibrary.ui.FormatUtility;
import org.skydiveapplibrary.ui.TableStyler;
import org.skydiveapplibrary.ui.TableStyler.TableRowLocation;
import org.skydiveapplibrary.util.RigReminderManager;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.ContextThemeWrapper;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;

public class RigEditActivity extends Activity
{
	// activity request codes
    private static final int REQUEST_NOTES = 0;
    private static final int REQUEST_COMPONENT = 1;
    private static final int REQUEST_REMINDER = 2;
    
	// repositories
	private RigRepository repository = new RigRepository(this);
	
	// data
	private boolean isEdit = false;
	private Rig rig;
	private RigComponent currentEditedComponent;
	private RigReminder currentEditedReminder;
	private boolean isUpdated = false;
	
	// listeners
	private OnClickListener notesEditListener = new OnClickListener()
	{
		@Override
		public void onClick(View view)
		{
			Intent intent = new Intent(RigEditActivity.this, NotesEditActivity.class);
            intent.putExtra(Constants.EXTRA_NOTES, rig.getNotes());
            startActivityForResult(intent, REQUEST_NOTES);
		}
	};
	private OnClickListener componentEditListener = new OnClickListener()
	{
		@Override
		public void onClick(View view)
		{
			currentEditedComponent = (RigComponent)view.getTag();
            Intent intent = new Intent(RigEditActivity.this, RigComponentEditActivity.class);
            intent.putExtra(Constants.EXTRA_RIG_COMPONENT_IS_EDIT, true);
            intent.putExtra(Constants.EXTRA_RIG_COMPONENT_NAME, currentEditedComponent.getName());
            intent.putExtra(Constants.EXTRA_RIG_COMPONENT_SERIAL_NUMBER, currentEditedComponent.getSerialNumber());
            intent.putExtra(Constants.EXTRA_RIG_COMPONENT_NOTES, currentEditedComponent.getNotes());
            startActivityForResult(intent, REQUEST_COMPONENT);
		}
	};
	private OnClickListener addComponentListener = new OnClickListener()
	{
		@Override
        public void onClick(View view)
        {
                currentEditedComponent = null;
                Intent intent = new Intent(RigEditActivity.this, RigComponentEditActivity.class);
                startActivityForResult(intent, REQUEST_COMPONENT);
        }
	};
	private OnClickListener reminderEditListener = new OnClickListener()
	{
		@Override
		public void onClick(View view)
		{
			currentEditedReminder = (RigReminder)view.getTag();
            Intent intent = new Intent(RigEditActivity.this, RigReminderEditActivity.class);
            intent.putExtra(Constants.EXTRA_RIG_REMINDER_IS_EDIT, true);
            intent.putExtra(Constants.EXTRA_RIG_REMINDER_NAME, currentEditedReminder.getName());
            intent.putExtra(Constants.EXTRA_RIG_REMINDER_INTERVAL, currentEditedReminder.getInterval());
            intent.putExtra(Constants.EXTRA_RIG_REMINDER_INTERVAL_UNIT, currentEditedReminder.getIntervalUnit());
            intent.putExtra(Constants.EXTRA_RIG_REMINDER_LAST_COMPLETED_DATE, currentEditedReminder.getLastCompletedDate());
            startActivityForResult(intent, REQUEST_REMINDER);
		}
	};
	private OnClickListener addReminderListener = new OnClickListener()
	{
		@Override
		public void onClick(View view)
		{
			currentEditedReminder = null;
            Intent intent = new Intent(RigEditActivity.this, RigReminderEditActivity.class);
            startActivityForResult(intent, REQUEST_REMINDER);
		}
	};
	private DialogInterface.OnClickListener deleteConfirmListener = new DialogInterface.OnClickListener()
	{
		@Override
		public void onClick(DialogInterface arg0, int arg1)
		{
			delete();
		}
	};
	
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
        super.onCreate(savedInstanceState);

		overridePendingTransition(R.anim.fadein,
				R.anim.hold);
        
        // load data
        loadData();
        
        // init ui
        initializeUI();
	}
	
	@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent)
    {	
            if (requestCode == REQUEST_NOTES && resultCode == RESULT_OK) 
            {
                    String notes = intent.getStringExtra(Constants.EXTRA_NOTES);
                    updateNotes(notes);
            }
            else if (requestCode == REQUEST_COMPONENT && resultCode == RESULT_OK)
            {
                    boolean isDelete = intent.getBooleanExtra(Constants.EXTRA_RIG_COMPONENT_DELETE, false);
                    String name = intent.getStringExtra(Constants.EXTRA_RIG_COMPONENT_NAME);
                    String serialNumber = intent.getStringExtra(Constants.EXTRA_RIG_COMPONENT_SERIAL_NUMBER);
                    String notes = intent.getStringExtra(Constants.EXTRA_RIG_COMPONENT_NOTES);
                    updateComponent(isDelete, name, serialNumber, notes);
            }
            else if (requestCode == REQUEST_REMINDER && resultCode == RESULT_OK)
            {
                    boolean isDelete = intent.getBooleanExtra(Constants.EXTRA_RIG_REMINDER_DELETE, false);
                    String name = intent.getStringExtra(Constants.EXTRA_RIG_REMINDER_NAME);
                    int interval = intent.getIntExtra(Constants.EXTRA_RIG_REMINDER_INTERVAL, 0);
                    TimeUnit intervalUnit = (TimeUnit)intent.getSerializableExtra(Constants.EXTRA_RIG_REMINDER_INTERVAL_UNIT);
                    Date lastCompletedDate = (Date)intent.getSerializableExtra(Constants.EXTRA_RIG_REMINDER_LAST_COMPLETED_DATE);
                    updateReminder(isDelete, name, interval, intervalUnit, lastCompletedDate);
            }
    }
	
	private void loadData()
	{
		// set isEdit flag
        Bundle extras = getIntent().getExtras();
        
        if (extras != null)
        {
        	isEdit = extras.containsKey(Constants.EXTRA_RIG_ID);

        	if (extras.containsKey(Constants.EXTRA_SEMI_TRANSPARENT_THEME))
        		setTheme(R.style.Theme_SemiTransparent);
        }
        
        // determine add vs. edit
        if (isEdit)
        {
                // editing
                int id = getIntent().getExtras().getInt(Constants.EXTRA_RIG_ID);
                rig = repository.getRig(id);
        }
        else
        {
                // adding
                rig = new Rig();
        }
	}
	
	private void initializeUI()
	{
		// show view
        setContentView(R.layout.rig_edit_view);
        
		// set subtitle text		
		if (this.findViewById(R.id.tabletLayout) != null)
		{
			InterfaceManager.getInstance().configureTabletUI(this, 
					isEdit ? R.string.rig_edit_label : R.string.rig_new_label);
		}
		else
		{
			InterfaceManager.getInstance().configurePhoneUI(this, 
					isEdit ? R.string.rig_edit_label : R.string.rig_new_label);
		}

		// set name
		EditText nField = (EditText) findViewById(R.id.RigNameField);
		nField.setText(rig.getName());
		
		// set primary
		CheckBox pField = (CheckBox) findViewById(R.id.RigPrimaryField);
		pField.setChecked(rig.isPrimary());
		
		if (!isEdit)
		{
			TableRow aRow = (TableRow) findViewById(R.id.RigArchivedTablerow);
			aRow.setVisibility(View.GONE);
		}
		else
		{
			// set archived
			CheckBox aField = (CheckBox) findViewById(R.id.RigArchivedField);
			aField.setChecked(rig.isArchived());
		}
		
		// set jump count
		TextView jcField = (TextView) findViewById(R.id.RigJumpCountField);
		jcField.setText(rig.getJumpCount() == 0 ? "0" :
			FormatUtility.toNumericString(rig.getJumpCount()));
		
		// set notes
		TextView notesField = (TextView) findViewById(R.id.RigNotesField);
		notesField.setText(rig.getNotes());
		notesField.setOnClickListener(notesEditListener);
		
		// init components UI
		initComponentsUI();
		
		// init reminders UI
		initRemindersUI();
	}
	
	private void initComponentsUI()
	{
		TableLayout tableLayout = (TableLayout) findViewById(R.id.RigComponentsTable);
		tableLayout.removeAllViews();
		for (int i = 0; i < rig.getComponents().size(); i++)
		{
			// get component
			RigComponent component = rig.getComponents().get(i);
			
			// create row, add to table
			TableRow row = createComponentTableRow(component, i == 0);
			tableLayout.addView(row);
		}
		
		// add 'add component' row
		TableRow addRow = createAddTableRow(
				rig.getComponents().size() <= 0,
				R.string.rig_add_component_label,
				addComponentListener);
		tableLayout.addView(addRow);
	}
	
	private void initRemindersUI()
	{
		TableLayout tableLayout = (TableLayout) findViewById(R.id.RigRemindersTable);
		tableLayout.removeAllViews();
		for (int i = 0; i < rig.getReminders().size(); i++)
		{
			// get reminder
			RigReminder reminder = rig.getReminders().get(i);
			
			// create row, add to table
			TableRow row = createReminderTableRow(reminder, i == 0);
			tableLayout.addView(row);
		}
		
		// add 'add reminder' row
		TableRow addRow = createAddTableRow(
				rig.getReminders().size() <= 0,
				R.string.rig_add_reminder_label,
				addReminderListener);
		tableLayout.addView(addRow);
	}
	
	private TableRow createComponentTableRow(RigComponent component, boolean first)
	{
		// create table row
		TableRow row = new TableRow(this);
		row.setTag(component);
		row.setOnClickListener(componentEditListener);
		// style
		TableStyler.styleTableRow(row, first ? TableRowLocation.First : TableRowLocation.Middle);
		
		// add component name
		TextView componentName = new TextView(this);
		componentName.setText(component.getName());
		// style
		TableStyler.styleTableRowTextView(this, componentName, false, false, true, 1);
		// add to row
		row.addView(componentName);
		
		return row;
	}
	
	private TableRow createReminderTableRow(RigReminder reminder, boolean first)
	{
		// create table row
		TableRow row = new TableRow(this);
		row.setTag(reminder);
		row.setOnClickListener(reminderEditListener);
		// style
		TableStyler.styleTableRow(row, first ? TableRowLocation.First : TableRowLocation.Middle);
		
		// add description
		TextView name = new TextView(this);
		name.setText(reminder.getName());
		// style
		TableStyler.styleTableRowTextView(this, name, false, false, false, 1);
		// add to row
		row.addView(name);
		
		// update fields based on due status
		Drawable icon = null;
		int textStyleId = R.style.FormFieldValueStyle;
		if (reminder.getDueStatus() == DueStatus.DueSoon)
		{
			textStyleId = R.style.DueSoonTextStyle;
		}
		else if (reminder.getDueStatus() == DueStatus.PastDue)
		{
			textStyleId = R.style.PastDueTextStyle;
			icon = getResources().getDrawable(R.drawable.skull_small);
		}
		name.setTextAppearance(this, textStyleId);
		name.setCompoundDrawablesWithIntrinsicBounds(null, null, icon, null);
		
		return row;
	}
	
	private TableRow createAddTableRow(boolean solo, int textId, OnClickListener listener)
	{
		// add 'add component' row
		TableRow row = new TableRow(this);
		row.setOnClickListener(listener);
		// style
		TableStyler.styleTableRow(row, solo ? TableRowLocation.Solo: TableRowLocation.Last);
		// add label
		TextView addLabel = new TextView(this);
		addLabel.setText(textId);
		// style
		TableStyler.styleTableRowTextView(this, addLabel, false, true, true, 1);
		// add to row
		row.addView(addLabel);
		
		return row;
	}
	
	private void showDeleteWarning()
	{
		// create alert dialog
		AlertDialog.Builder builder = new AlertDialog.Builder(
				new ContextThemeWrapper(this, android.R.style.Theme_Holo_Dialog));
		builder.setMessage(R.string.rig_delete_warning);
		builder.setIcon(android.R.drawable.ic_dialog_alert);
		builder.setTitle(R.string.delete_confirmation);
		builder.setPositiveButton(R.string.yes_button, deleteConfirmListener);
		builder.setNegativeButton(R.string.no_button, null);
		AlertDialog dialog = builder.create();
		// show dialog
		dialog.show();
	}
	
	private void updateNotes(String notes)
	{
		// update component
        rig.setNotes(notes);
        
        // update ui
        TextView notesField = (TextView)findViewById(R.id.RigNotesField);
        notesField.setText(rig.getNotes());
        
        isUpdated = true;
	}
	
	private void updateComponent(boolean isDelete, String name, String serialNumber, String notes)
    {
	    // update reminder and UI
	    if (currentEditedComponent == null)
	    {
	        // add
	        RigComponent component = new RigComponent();
	        component.setName(name);
	        component.setSerialNumber(serialNumber);
	        component.setNotes(notes);
	        rig.getComponents().add(component);
	    }
	    else if (isDelete)
	    {
	        // delete
	        rig.getComponents().remove(currentEditedComponent);
	    }
	    else
	    {
	        // update
	        currentEditedComponent.setName(name);
	        currentEditedComponent.setSerialNumber(serialNumber);
	        currentEditedComponent.setNotes(notes);
	    }
	    isUpdated = true;
	    
	    // update UI
	    initComponentsUI();
    }
	
	private void updateReminder(boolean isDelete, String name, int interval, TimeUnit intervalUnit, Date lastCompletedDate)
    {
	    // update reminder and UI
	    if (currentEditedReminder == null)
	    {
	        // add reminder
	        RigReminder reminder = new RigReminder();
	        reminder.setName(name);
	        reminder.setInterval(interval);
	        reminder.setIntervalUnit(intervalUnit);
	        reminder.setLastCompletedDate(lastCompletedDate);
	        rig.getReminders().add(reminder);
	    }
	    else if (isDelete)
	    {
	        // delete
	        rig.getReminders().remove(currentEditedReminder);
	    }
	    else
	    {
	        // update
	        currentEditedReminder.setName(name);
	        currentEditedReminder.setInterval(interval);
	        currentEditedReminder.setIntervalUnit(intervalUnit);
	        currentEditedReminder.setLastCompletedDate(lastCompletedDate);
	    }
	    isUpdated = true;
	    
	    // update UI
	    initRemindersUI();
    }
	
	private void commitChangesToRig()
	{
		// set name
        EditText nField = (EditText)findViewById(R.id.RigNameField);
        rig.setName(nField.getText().toString());
        
        // set primary
        CheckBox pField = (CheckBox)findViewById(R.id.RigPrimaryField);
        rig.setPrimary(pField.isChecked());
        
        // set archived
        CheckBox aField = (CheckBox)findViewById(R.id.RigArchivedField);
        rig.setArchived(aField.isChecked());
	}
	
	private void save()
	{
		commitChangesToRig();

		// save
		if (isEdit)
		{
			repository.updateRig(rig);
		}
		else
		{
			repository.addRig(rig);
		}
		
		// update reminders
		RigReminderManager.getInstance().remindersChanged();
		
		// finish
		close();
	}
	
	private void delete()
	{
		// delete aircraft
		repository.deleteRig(rig);
		
		// update reminders
		RigReminderManager.getInstance().remindersChanged();
		
		// finish
		close();
	}
	
	private Boolean checkForChanges()
	{
		// check name
		EditText nField = (EditText) findViewById(R.id.RigNameField);
		if (!rig.getName().equals(nField.getText().toString()))
			return true;
		
		// check primary
		CheckBox pField = (CheckBox) findViewById(R.id.RigPrimaryField);
		if (rig.isPrimary() != pField.isChecked())
			return true;
		
		// check archived
		CheckBox aField = (CheckBox) findViewById(R.id.RigArchivedField);
		if (rig.isArchived() != aField.isChecked())
			return true;
		
		return false;
	}
	
	private void showSaveWarning()
	{
		// create alert dialog
		AlertDialog.Builder builder = new AlertDialog.Builder(
				new ContextThemeWrapper(this, android.R.style.Theme_Holo_Dialog));
		builder.setMessage(R.string.gear_list_save_warning);
		builder.setIcon(android.R.drawable.ic_dialog_alert);
		builder.setTitle(R.string.save_confirmation);
		builder.setPositiveButton(R.string.yes_button, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int id) {
				save();
	           }       
		});
		builder.setNeutralButton(R.string.no_button, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int id) {
				close();
	           }       
		});
		builder.setNegativeButton(R.string.cancel_button, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int id) {}       
		});
			
		AlertDialog dialog = builder.create();
		// show dialog
		dialog.show();
	}
	
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    	MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_save, menu);
    	
        if (isEdit)
        	inflater.inflate(R.menu.menu_delete, menu);
        
        inflater.inflate(R.menu.menu_back, menu);
        return true;
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle item selection
        switch (item.getItemId())
        {
        case R.id.menu_save:
    		save();
            return true;
            
        case R.id.menu_back:		
			onBackPressed();
            return true;
            
        case R.id.menu_delete:
        	showDeleteWarning();
            return true;
            
        default:
            return super.onOptionsItemSelected(item);
        }
    }
    
    @Override
    public void onBackPressed()
    {
    	if (isUpdated || !isEdit || checkForChanges())
		{
			showSaveWarning();
		} else 
		{
			close();
		};
    }
    
    private void close()
    {
    	finish();
		overridePendingTransition(R.anim.hold,
				R.anim.fadeout);
    }
}
